﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IndexersAndOperators
{
    class ComplexNumber
    {
        private double realPart;
        private double imagineryPart;

        public double RealPart
        {
            get
            {
                return this.realPart;
            }
            set
            {
                this.realPart = value;
            }
        }
        public double ImagineryPart
        {
            get
            {
                return this.imagineryPart;
            }
            set
            {
                this.ImagineryPart = value;
            }
        }

        public ComplexNumber()
            : this(0, 0)
        {
        }
     
        public ComplexNumber(double realPart, double imagineryPart)
        {
            this.realPart = realPart;
            this.imagineryPart = imagineryPart;
        }

        public static ComplexNumber operator +(ComplexNumber complexNumber1, ComplexNumber complexNumber2)
        {
            ComplexNumber result = new ComplexNumber(complexNumber1.RealPart + complexNumber2.RealPart, complexNumber1.ImagineryPart + complexNumber2.ImagineryPart);
            return result;
        }

        public static ComplexNumber operator -(ComplexNumber complexNumber1, ComplexNumber complexNumber2)
        {
            ComplexNumber result = new ComplexNumber(complexNumber1.RealPart - complexNumber2.RealPart, complexNumber1.ImagineryPart - complexNumber2.ImagineryPart);
            return result;
        }

        public static ComplexNumber operator *(ComplexNumber complexNumber1, ComplexNumber complexNumber2)
        {
            ComplexNumber result = new ComplexNumber(complexNumber1.RealPart*complexNumber2.RealPart - complexNumber1.ImagineryPart*complexNumber2.ImagineryPart, complexNumber1.ImagineryPart*complexNumber2.RealPart + complexNumber2.ImagineryPart*complexNumber1.RealPart);
            return result;
        }

        public static ComplexNumber operator /(ComplexNumber complexNumber1, ComplexNumber complexNumber2)
        {
            double denominator = complexNumber2.RealPart * complexNumber2.ImagineryPart;
            if (denominator != 0)
            {
                ComplexNumber result = new ComplexNumber((complexNumber1.RealPart * complexNumber2.RealPart + complexNumber1.ImagineryPart * complexNumber2.ImagineryPart) / (denominator), (complexNumber1.ImagineryPart * complexNumber2.RealPart - complexNumber2.ImagineryPart * complexNumber1.RealPart) / (denominator));
                return result;
            }
            else
            {
                throw new DivideByZeroException("The denominator is zero");
            }
        }
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(this.RealPart.ToString());

            if (this.ImagineryPart > 0)
            {
                builder.Append(" + " + this.ImagineryPart.ToString() + "i");
            }
            else
            {
                builder.Append(" - " + Math.Abs(this.ImagineryPart).ToString() + "i");
            }
            return builder.ToString();
        }

        public static explicit operator double(ComplexNumber number)
        {
            return number.RealPart;
        }

        public static implicit operator ComplexNumber(double number)
        {
            ComplexNumber complexNumber = new ComplexNumber(number, 0);
            return complexNumber;
        }

        public double this[int index]
        {
            get 
            {
                if (index == 0)
                {
                    return this.RealPart;
                }
                else if (index == 1)
                {
                    return this.ImagineryPart;
                }
                else
                {
                    throw new IndexOutOfRangeException(String.Format("Index {0} is invalid!", index));

                }
            }
            set
            {
                if (index == 0)
                {
                    this.RealPart = value;
                }
                else if (index == 1)
                {
                    this.ImagineryPart = value;
                }
                else
                {
                    throw new IndexOutOfRangeException(String.Format("Index {0} is invalid!", index));

                }
            }
        }
    
    
    
    
    

        

    }
}
